-
Notifications
You must be signed in to change notification settings - Fork 896
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix panic in annotated_snippet dependency (GitHub issue #4968). #5629
base: master
Are you sure you want to change the base?
Conversation
Thanks for your first contribution to rustfmt 🎉 when you have a moment, could you expand on why the change implemented here addresses the panic in Also, if this does resolve the issue would you mind looking into the following related issues to see if they're also solved by this:
It would be great to add additional test cases for each issue that is also resolved by this PR. |
Hi, testing locally, this PR does fix the examples in the first 3 links. I can add them as proper test cases if desired. Actually, this PR is not directly related to the changes in #5039. Currently, rustfmt always treats tabs as #5039 would prevent rustfmt from producing an error at all in those cases, but does not address the following issue (which is only what this PR attempts to fix; this PR doesn't include the variable-width arithmetic for tabs). If rustfmt tries to display an error using the annotated_snippet dependency, there may be a panic in the dependency due to the following discrepancy:
I had been running locally the changes suggested by camsteffen in #5039 to fix this discrepancy. Since I only just got around to trying to submit a proper PR/fix, I forgot that #5039 itself isn't directly related. The suggested changes (which this PR is for) is for rustfmt to build its internal buffer always replacing tabs with the corresponding number of spaces (which is orthogonal to the discussion of how many spaces a tab should be worth). This way, the "effective width" and "actual offsets" are consistent. I took camsteffen's suggestions as is - which includes counting each character Hopefully my explanation is good. The example in #5431, as far as what I can tell the user wants, is the same, and should be fixed as well. I believe #5546 wishes there to be "soft tabs" and "hard tabs":
This PR doesn't add that feature. |
It was great! Thank you for being so thorough 😁. It also helped that you linked to the implementation used by
Please and thank you! It's always good to have more test cases! |
Hi, my apologies, I just saw/realized that you asked to add the additional test cases in your original post. I also have to apologize for unclear wording on my part. By "this PR does fix the examples in the first 3 links", I meant it fixes rustfmt causing annotated_snippet to panic. To reiterate/summarize, rustfmt and annotated_snippet count characters/offsets differently. If rustfmt decides to report an error, there may be a panic in annotated_snippet because the range rustfmt passes to annotated_snippet may be out of range (for annotated_snippet). To me, this is the only (hard) bug (and I don't think this would be controversial). #5039 desires to relax when rustfmt decides there is an error, by counting tabs as "up to #5546 also desires different rustfmt behaviour, revolving around whether This PR doesn't change rustfmt's behaviour of when it decides something is an error - it doesn't resolve GitHub issues #5039 and #5546. The test case in #4968 (comment) is then functionally identical to the test case I have originally added. I personally feel and would guess that rustfmt needs further discussion if the requested behaviour in #5039 or #5546 is to be adopted. #5546 would require nontrivial work, but if #5039 is definitely desired I am happy to apply the necessary changes in this PR, or submit it as a different fix (hopefully I have made clear now that there are different issues (in the general sense) that could be fixed). If it's still desired to have #4968 (comment) as a test case, I am happy to add it. If it's desired to have the other examples as "nolonger crashes", I am also happy to add it. But I felt I gave the wrong impression about "fixing" based on my original poor wording. Also, if this PR is to be accepted, I believe I should change my commit message to be more clear based on this discussion. |
I just rebased the changes in this PR with the latest upstream code (and force pushed). |
Added missing On 37489e4 (
In this PR, the CI failed becaused rustfmt failed to format that test case - but it reports the error properly. I didn't look deeply into it, but it wasn't obvious to me how to make a test case that's supposed to fail to format (this PR should be fixed before it's accepted - any pointers on how to do such a test case would be appreciated) |
@ytmimi -- any chance we could review this PR? I'm hitting very similar issues :) |
* This change is based on the code review by camsteffen on PR rust-lang#5039 by karyon: have rustfmt internally replace tabs with the corresponding number of spaces, so that columns/indices in the buffer passed to annotated_snippet are counted unambiguously.
* With hard_tabs, rustfmt preserves tabs and counts them as multiple characters/columns (based on configuration). * The annotated_snippet dependency, used to display errors, always counts tabs as 1 character. * If rustfmt tries to report an error on a line containing tabs, the indices are mismatched. * annotated_snippet will display the wrong range of the source code slice; in the extreme case, it can panic with out-of-bounds access. * The test case added in this commit is expected to currently fail, since this commit doesn't include the fix.
@stswidwinski sorry to hear that you hit this case. I'll revisit this one when I've got some time. I also want to highlight that #6084 was opened a while ago and I think it also addresses this issue. I'll need to double check that to be sure, but you might also want to watch for progress on that PR (when I've got time to revisit it as well). |
Ref #4968. Changes based on the code review suggestions in #5039. Tabs are counted as
config.tab_spaces
columns, but theannotated_snippet
dependency counts tabs as 1 space. This difference may lead to a panic inannotated_snippet
, which can be seen in the test-case added (with this PR's change, it should nolonger panic).Note that #5039 is about changing tabs to "align to
config.tab_spaces
columns". But the code review suggestion by camsteffen also fixes the panic. This PR doesn't change the arithmetic (tabs are still always counted as a fixed number of spaces) - but just addresses the panic in the dependency.